iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0
Modern Web

Rust 的戰國時代:探索網頁前端工具的前世今生系列 第 9

Day 09:為什麼 Vite 的冷啟動可以這麼快?

  • 分享至 

  • xImage
  •  

day 09 banner

(Photo by Jr Korpa)

前言

昨天簡介了這麼多套 bundler、build tool 後,今天想開始來動手做一些東西,但 Rust-based bundler 有這麼多套要選哪一套切入開始研究起呢?

在一番考察後,認為以目前現代前端工具鏈中,Rspack 與 Vite 生態系中的 Rolldown 是最有深入研究的價值。

為什麼這麼說呢?Rspack 的優勢在於更好地兼容 Webpack,且相對於 Rolldown 來說是更成熟的 bundler。

而 Vite 從今年 VueConf US 2024 中 Evan You 的這場《Vue & Vite Updates》演講中的講古就可以見識到,Vite 從 2020 一個睡前讓他 hack 到早上六點的點子,時至今日已經成長為一個龐大的前端工具鏈生態系,除 Vue 體系自己之外的許多現代前端框架如 Qwik、Solid.js、SvelteKit、Astro、Remix 等預設啟用專案的構建工具都相繼加入:

VueConf US 2024

儘管 Rollup 仍有效能問題,且 Rolldown 尚未成熟,幾經考慮後決定還是從 Vite 下手,純粹是因為關於 Vite 背後有一些革命性的運作原理我更有興趣,如果後面篇幅還夠再來補上 Rspack 的部分,理想上弄懂了一套最完整的,那其他幾套應該只是大同小異。

關於 Vite 的一些 What 與 Why

這裡試著列出一些開始研究前的一些我不懂的問題,接下來幾天我們會試著從這些問題出發來實驗與理解運作原理:

  • 為什麼 Vite 的冷啟動可以這麼快?
  • 什麼是 pre-bundling?
  • Vite 跟 esbuild 的關係是什麼?
  • 為什麼 Vite 要用 Rollup 做為 production build 的 bundler,而不選用 esbuild?
  • HMR (Hot Module Replacement)的原理是什麼?
  • 什麼是 Rolldown?跟 Rollup 差在哪?
  • 什麼是 OXC?跟 SWC 有何關係?為什麼 Vite 底層會需要這個工具?

期待在幾天後我們能一起回頭來回答這些問題。

為什麼 Vite 的冷啟動可以這麼快?

不知道你有沒有遇過一些比較有年代的大型專案,在啟動 dev server 時,往往可能會需要先初始化個數分鐘,這樣的開發體驗隨著專案不斷長大就會成為一個問題。就像這個 Vite 官方教學影片底下有人留了一個反諷:

joke

而昨天有提到 Vite 在其 dev server 的實作上使用了 Native-ESM-based 的架構,那這個架構實際上與過往傳統的 bundle-based 架構的工具差在哪裡呢?以下我們可以先實際用個範例體驗一下。

實際參考文件用以下指令啟一個新的專案,為避免太複雜,先用最單純的 vanilla 模板:

$ pnpm create vite hello-vite --template vanilla
$ cd hello-vite
$ pnpm install
$ pnpm run dev

上面指令執行成功後,在瀏覽器打開 http://localhost:5173 這個網址應該能看到以下左側的畫面:

demo1

上面可以先打開 dev tool 切到 network 下,另外可以將 JSHide extension URLs 這兩個 filter 開起來,比較好分析實際載入 JS 模組的 request 們。

回到我們剛建好的專案中,看到 index.html 這個檔案。你會看到主程式的進入點是 main.js 也就是我們在上圖中打開的檔案:

<script type="module" src="/main.js"></script>

你可能會好奇為什麼在瀏覽器上會看到 importexport 這些 ESM 的語法,這裡的關鍵就在於 type=”module” 這個屬性。這個屬性告訴瀏覽器可以用 ESM 的標準去識別這個模組,而目前這個特性在現代瀏覽器也都已經廣泛支援 (ref)。

假如你今天試著將上面的 type=”module” 移除,就會看到 console 上噴錯:

demo2

以往傳統 dev server 在冷啟動或修改檔案後,一定要經過「從進入點分析依賴模組、轉譯模組、打包」這些步驟後才能完成 server 的初始化,就像昨天看到的這張圖:

bundle

而 Vite 一改上面這個流程,改利用瀏覽器原生能支援 ESM 的這個特性,來讓 dev server 省略打包過程直接啟動。當 dev server 收到 request 後才做即時編譯:

esm

而其中的這個即時編譯似乎還牽涉到了 HMR 與 pre-bundling 這兩件事,明天我會再繼續來深入了解這部分。

延伸閱讀

雖然 Vite 相關的主題還沒追完,這邊先附上一些除了官方文件外找到很不錯的學習資源,有興趣的讀者也可以從這些資源去延伸學習:


上一篇
Day 08:現代 bundler、build tool 簡介 (Vite、esbuild、Rspack、Rolldown、Turbopack)
下一篇
Day 10:用實驗來理解 Vite 的 dependency pre-bundling 是什麼 (1)
系列文
Rust 的戰國時代:探索網頁前端工具的前世今生30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言